﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HotShot.Entities;
using HotShot.Service.Entities;
using HotShot.Entities.Messages;

namespace HotShot.Service.BusinessLogic
{
    public static class Messages
    {
        public static BaseMessage InitNode()
        {
            return new BaseMessage
            {
                SenderAddress = ClusterProcessorLogic.Current.ProcessorId,
                MessageType = "InitNode",
                XmlPayload = new ProcessorNodeDescriptor
                {
                    NodeId = ClusterProcessorLogic.Current.ProcessorId,
                }.ToXml(),
                ReturnAddress = ClusterProcessorLogic.Current.ProcessorId,
            };
        }

        public static BaseMessage KnownNodes(IEnumerable<ProcessorNodeDescriptor> nodeList)
        {
            return new BaseMessage
            {
                SenderAddress = ClusterProcessorLogic.Current.ProcessorId,
                MessageType = "KnownNodes",
                XmlPayload = nodeList.ToList().ToXml(),
            };
        }

        public static BaseMessage Ping(string destination)
        {
            var nodeList = ClusterProcessorLogic.Current.GetKnownNodes(true, true);
            
            return new BaseMessage
            {
                SenderAddress = ClusterProcessorLogic.Current.ProcessorId,
                ReturnAddress = ClusterProcessorLogic.Current.ProcessorId,
                Destination = destination ?? ClusterProcessorLogic.Current.ProcessorId,
                MessageType = "Ping",
                XmlPayload = nodeList.ToXml(),
            };
        }

        public static BaseMessage Store(StorageEntity entity, string destination)
        {
            var nodeList = ClusterProcessorLogic.Current.GetKnownNodes(true, true);

            return new BaseMessage
            {
                SenderAddress = ClusterProcessorLogic.Current.ProcessorId,
                ReturnAddress = ClusterProcessorLogic.Current.ProcessorId,
                Destination = destination ?? ClusterProcessorLogic.Current.ProcessorId,
                MessageType = "Store",
                XmlPayload = entity.ToXml(),
            };
        }

        public static BaseMessage StoreResult(StorageEntity entity)
        {
            var nodeList = ClusterProcessorLogic.Current.GetKnownNodes(true, true);

            return new BaseMessage
            {
                SenderAddress = ClusterProcessorLogic.Current.ProcessorId,
                ReturnAddress = null,
                Destination = null,
                MessageType = "StoreResult",
                XmlPayload = entity.ToXml(),
            };
        }
        public static BaseMessage Retrieve(string key, string destination)
        {
            var nodeList = ClusterProcessorLogic.Current.GetKnownNodes(true, true);

            return new BaseMessage
            {
                SenderAddress = ClusterProcessorLogic.Current.ProcessorId,
                ReturnAddress = ClusterProcessorLogic.Current.ProcessorId,
                Destination = destination,
                MessageType = "RetrieveRequest",
                XmlPayload = new StorageEntity
                {
                    Key = key,
                }.ToXml(),
            };
        }

        public static BaseMessage RetrieveResultInternal(StorageEntity entity, string destination)
        {
            var nodeList = ClusterProcessorLogic.Current.GetKnownNodes(true, true);

            return new BaseMessage
            {
                SenderAddress = ClusterProcessorLogic.Current.ProcessorId,
                ReturnAddress = ClusterProcessorLogic.Current.ProcessorId,
                Destination = destination ?? ClusterProcessorLogic.Current.ProcessorId,
                MessageType = "RetrieveResultInternal",
                XmlPayload = entity.ToXml(),
            };
        }

        public static BaseMessage RetrieveResult(List<StorageEntity> entity)
        {
            var nodeList = ClusterProcessorLogic.Current.GetKnownNodes(true, true);

            return new BaseMessage
            {
                SenderAddress = ClusterProcessorLogic.Current.ProcessorId,
                ReturnAddress = ClusterProcessorLogic.Current.ProcessorId,
                Destination = null,
                MessageType = "RetrieveResult",
                XmlPayload = entity.ToXml(),
            };
        }
    }
}
